-module(part1).
-export([fib/1, deep_sum/1, adjacent_duplicates/1, concatenate_all/1, perimeter/1, permutations/1]).

%%Question 1
fib(N) -> fibtail(N, 0, 1).

fibtail(0, Current, _Next) -> Current;
fibtail(N, Current, Next) -> 
	fibtail(N - 1, Next, Current + Next).
	
%%Question 2
adjacent_duplicates(L) -> 
	adjacent_duplicates_helper(L, []).

adjacent_duplicates_helper([Head | [Head | Tail]], Result) ->
	adjacent_duplicates_helper([Head | Tail], Result ++ [Head]);
adjacent_duplicates_helper([_Head | [Head2 | Tail]], Result) ->
	adjacent_duplicates_helper([Head2 | Tail], Result);
adjacent_duplicates_helper([_Head | _Tail], Result) ->
	Result.
	
%%Question 3
deep_sum(L) ->
	deep_sum_helper(lists:flatten(L), 0).

deep_sum_helper([], Result) ->
	Result;
deep_sum_helper([Head | Tail], Result) ->
	deep_sum_helper(Tail, Result + element(1, Head) + element(2, Head)).

%%Question 4
concatenate_all(L) ->
	lists:append(L).

%%Question 5
perimeter(Shape) ->
	perimeter_helper(Shape).

perimeter_helper({circle, Radius}) ->
	2 * math:pi() * Radius;
perimeter_helper({rectangle, Width, Height}) ->
	2 * Width + 2 * Height;
perimeter_helper({right_triangle, Width, Height, Hypot}) ->
	Width + Height + Hypot.
	
%%Question 6

%%The base case is the empty list (permutations_helper([]) -> [[]];)
%%The next line calculates the list of [Head | Tail] such that
%%	Head is taken from the list L, and
%%	Tail is taken from the permutations of the rest of the list (subtracting the Head). 

%%	In more detail, this constructs a list [Head | Tail] such that (||)
%%	Head <- L generates the head of the list, and
%%	Tail <- permutations_helper(L--[Head]) generates the permutations of the list without the Head (-- subtracts the Head from the List).
%%	The resulting Heads and Tails are paired together. 

%%Sources
%%	http://en.wikipedia.org/wiki/Erlang_(programming_language) where it says "The expression [Front || Front <- Rest, Front < Pivot] is a list comprehension"
%%	http://schemecookbook.org/Erlang/ListListMinus where it says "subtraction (--). The subtraction operator provides the same functionality as the lists:subtract function"

permutations(L) -> permutations_helper(L).
	
permutations_helper([]) -> [[]];
permutations_helper(L)  -> 
	[[Head | Tail] || 
		Head <- L, 
		Tail <- permutations_helper(L--[Head])].





















